
//  了解  hash.Code() 方法


import java.util.HashMap;
import java.util.Objects;

class Person {
    public String id;
    public Person(String id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "person{" +
                "id=" + id +
                '}';
    }
}

class Person2 {
    public String id;
    public Person2(String id) {
        this.id = id;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person2 person2 = (Person2) o;
        return Objects.equals(id, person2.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    @Override
    public String toString() {
        return "person{" +
                "id=" + id +
                '}';
    }
}


//      K,V都是引用类型
public class HashBuck2<K,V> {
    static class Node<K,V> {
        public K key;
        public V val;
        public Node<K,V> next;

        public Node(K key, V val) {
            this.key = key;
            this.val = val;
        }
    }

    public Node<K,V>[] array = (Node<K,V>[])new Node[10];//这里最好用object创建数组
    public int usedSize;

    public void put(K key, V val) {
        int hash = key.hashCode();//通过hashCode()将类型转换为int
        int index = hash % this.array.length;

        Node<K,V> cur = array[index];
        while (cur != null) {
//            if (cur.val == val) { //因为是引用类型 不能使用==来比较了
            if (cur.key.equals(key)) {
                cur.val = val;
                return;
            } else {
                cur = cur.next;
            }
        }
//        我们可以了解 hashCode确定 下标 equals确定值
//        hashCode一样 equals不一定一样;
//        equals一样    hashCode一定一样;
//        egg:  如果下标是   美（hashCode） 它下面可能有 （equals）美丽 美景 美好

        Node<K,V> node = new Node<>(key,val);
        node.next = this.array[index];
        this.array[index] = node;
        this.usedSize++;

//        这里我们先不考虑扩容
    }

    public V get(K key) {
        int hash = key.hashCode();//通过hashCode()将类型转换为int
        int index = hash % this.array.length;
        Node<K,V> cur = this.array[index];
        while (cur != null) {
//            if (cur.key == key) {//这里也需要用equals去比较不能用==
            if (cur.key.equals(key)) {
                return cur.val;
            }else {
                cur = cur.next;
            }
        }
        return null;
    }













    public static void main1(String[] args) {
        Person person1 = new Person("123");
        Person person2 = new Person("123");

        System.out.println(person1.hashCode());//460141958
        System.out.println(person2.hashCode());//1163157884
//        不一样 并且数还很大 我们如何获得一样的数呢
//        需要自己生成 在类Person2自己写或者编译器自己生成hashCode()
//           但我们会发现在生成时 equals() 和 hashCode()同时存在  为什么要同时重写呢？
    }

    public static void main2(String[] args) {
        Person2 person1 = new Person2("123");
        Person2 person2 = new Person2("123");

        System.out.println(person1.hashCode());//48721
        System.out.println(person2.hashCode());//48721

//        我们可以了解
        HashMap<Person2,String> map = new HashMap<>();
//        这里的自定义类型Person2要重写我们的hashCode  不然会出现本意两个一样的值
//        但在代码逻辑上是不一样的
    }


    public static void main(String[] args) {
        Person2 person1 = new Person2("123");
        Person2 person2 = new Person2("123");
        HashBuck2<Person2,String> hashBuck2 = new HashBuck2<>();
        hashBuck2.put(person1,"cat");
        System.out.println(hashBuck2.get(person2));//cat
    }




}
